package cn.lyjuan.first.netty.demo._5_netty_heartbeat.client;

import cn.lyjuan.first.netty._4_netty_serialize.msg.codec.MessageCodec;
import cn.lyjuan.first.netty._4_netty_serialize.msg.reader.ReaderFactory;
import cn.lyjuan.first.netty._4_netty_serialize.msg.reader.impl.HelloReaderImpl;
import cn.lyjuan.first.netty._4_netty_serialize.msg.reader.impl.MsgReaderImpl;
import cn.lyjuan.first.netty.demo._5_netty_heartbeat.client.handler.ClientHandler;
import cn.lyjuan.first.netty.demo._5_netty_heartbeat.client.handler.ClientHeartHandler;
import cn.lyjuan.first.netty.demo._5_netty_heartbeat.client.handler.ReconnectHandler;
import cn.lyjuan.first.netty.demo._5_netty_heartbeat.cst.HeartbeatConst;
import cn.lyjuan.first.netty.demo._5_netty_heartbeat.msg.reader.impl.HeartReaderImpl;
import cn.lyjuan.first.netty.demo._5_netty_heartbeat.server.Server;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.timeout.IdleStateHandler;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.Timer;
import java.util.concurrent.TimeUnit;

public class Client
{
    private static Logger log = LogManager.getLogger(Client.class);

    public static final String HOST = "localhost";

    public static void main(String[] args) throws InterruptedException
    {
        Bootstrap strap = new Bootstrap();
        NioEventLoopGroup group = new NioEventLoopGroup();

        Channel chl = start(strap, group);

    }

    private static Channel start(Bootstrap strap, NioEventLoopGroup group) throws InterruptedException
    {

        ReaderFactory readerFactory = new ReaderFactory();
        readerFactory.addReader(new HelloReaderImpl());
        readerFactory.addReader(new MsgReaderImpl());
        readerFactory.addReader(new HeartReaderImpl());

        // 启动
        ChannelFuture future = strap.group(group)
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<SocketChannel>()
                {
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception
                    {
                        ch.pipeline().addLast(new ReconnectHandler(strap, HOST, Server.PORT));
                        ch.pipeline().addLast(new IdleStateHandler(0, HeartbeatConst.IDLE_TIMEOUT - 1, 0, TimeUnit.SECONDS));
                        ch.pipeline().addLast(new MessageCodec().setReaderFactory(readerFactory));
                        ch.pipeline().addLast(new ClientHeartHandler());
                        ch.pipeline().addLast(new ClientHandler());
                    }
                })
                .option(ChannelOption.SO_KEEPALIVE, true)
                .connect(HOST, Server.PORT);

        future.sync();

        log.info("client start");
        return future.channel();
    }
}
